#include "agent.h"

CAgentImpl::CAgentImpl(void)
{
	
}
CAgentImpl::~CAgentImpl(void)
{
	logi("CAgentImpl::~CAgentImpl");
}
std_method_impl CAgentImpl::SetId(unsigned int id)
{
	m_id = id;
	return S_OK;
}
std_method_impl CAgentImpl::Bind(LPCSTR addr, int len)
{
	HRESULT hr = S_OK;

	hr = this->UnBindEvent();
	rc_assert(hr == S_OK, E_FAIL)

	BasePtr pBase;

	hr = this->QueryInterface(IID_IBase, (void**)&pBase);
	rc_assert(hr == S_OK, E_FAIL)

	hr = this->BindEvent(pBase);
	rc_assert(hr == S_OK, E_FAIL)

	hr = this->ConnectChannel(addr, len, BUS_OP_CONNCET);
	rc_assert(hr == S_OK, E_FAIL)

	m_sem.Wait();

	return S_OK;
}
std_method_impl CAgentImpl::Close()
{
	return this->CloseChannel();
}
std_method_impl CAgentImpl::Recv(IBase* pBase)
{
	return S_OK;
}
std_method_impl CAgentImpl::Send(IBase* pBase)
{
	return S_OK;
}
std_method_impl CAgentImpl::OnComplete(IBase *pOperation, event_id event, ULONG error_code)
{

	HRESULT hr = S_OK;

	if (error_code == S_SUCCESS) {

		switch (event)
		{
		case BUS_OP_CONNCET:
			hr = OnConnected(pOperation);
			break;
		case BUS_OP_SEND_SEQ:
			hr = OnSendSeqed(pOperation);
			break;
		case BUS_OP_RECV_SEQ_ACK:
			hr = OnRecvSeqAcked(pOperation);
			break;
		case BUS_OP_SEND_ACK:
			hr = OnSendAcked(pOperation);
			break;
		case BUS_OP_RECV_HEAD:
			hr = OnRecvHeaded(pOperation);
			break;
		case BUS_OP_RECV:
			hr = OnRecved(pOperation);
			break;
		default:
			loge("CConsumerImpl::OnComplete");
			break;
		}
	}

	m_sem.Post();
	return S_OK;
}

std_method_impl CAgentImpl::OnConnected(IBase *pIBase)
{
	HRESULT hr = S_OK;

	BUFFER_PTR	ptr = NULL;
	hr = this->GetWritePtr(&ptr);
	rc_assert(hr == S_OK, E_FAIL)

	hr = BusProtocol_Init_Head(ptr, m_id, 0, NDC_PRODUCER, BUS_CONSUMER_VERSION);
	rc_assert(hr == S_OK, E_FAIL)

	hr = BusProtocol_1st(ptr, BUS_SEQ_VALUE, BUS_NULL_VALUE);
	rc_assert(hr == S_OK, E_FAIL)

	hr = this->OnWriteChannel(0, BUS_PROTOCOL_HEAD_LEN, BUS_OP_SEND_SEQ);
	rc_assert(hr == S_OK, E_FAIL)

	return hr;
}

std_method_impl CAgentImpl::OnSendSeqed(IBase *pIBase)
{
	HRESULT hr = S_OK;

	hr = this->OnReadChannel(0, BUS_PROTOCOL_HEAD_LEN, BUS_OP_RECV_SEQ_ACK);
	rc_assert(hr == S_OK, E_FAIL)

	return hr;
}

std_method_impl CAgentImpl::OnRecvSeqAcked(IBase *pIBase)
{
	HRESULT hr = S_OK;

	OperationPtr	pIOperation;
	BUFFER_SIZE		TransferedBytes = 0;
	BUFFER_PTR		ptr = NULL;

	hr = GetObject(pIBase, pIOperation);
	rc_assert(hr == S_OK, E_FAIL)

	pIOperation->GetTransfered(&TransferedBytes);
	rc_assert(TransferedBytes != 0, E_FAIL)

	hr = pIOperation->GetPtr(&ptr);
	rc_assert(hr == S_OK, E_FAIL)

	unsigned int s = 0;
	unsigned int a = 0;

	hr = BusProtocol_Get_Seq_Ack(ptr, &s, &a);
	rc_assert(hr == S_OK, E_FAIL)

	logi("c_recv==>seq:%u,ack:%u", a, s);

	hr = BusProtocol_3rd(ptr, s, a);
	rc_assert(hr == S_OK, E_FAIL)

	hr = this->WriteStream(ptr, 0, BUS_PROTOCOL_HEAD_LEN);
	rc_assert(hr == S_OK, E_FAIL)

	hr = this->OnWriteChannel(0, BUS_PROTOCOL_HEAD_LEN, BUS_OP_SEND_ACK);
	rc_assert(hr == S_OK, E_FAIL)

	return hr;
}
std_method_impl CAgentImpl::OnSendAcked(IBase *pIBase)
{
	HRESULT hr = S_OK;

	return hr;
}
std_method_impl CAgentImpl::OnRecvHeaded(IBase *pIBase)
{
	HRESULT hr = S_OK;

	return hr;
}
std_method_impl CAgentImpl::OnRecved(IBase *pIBase)
{
	HRESULT hr = S_OK;

	return hr;
}
std_method_impl CAgentImpl::OnSendHeaded(IBase *pIBase)
{
	HRESULT hr = S_OK;

	return hr;
}
std_method_impl CAgentImpl::OnSended(IBase *pIBase)
{
	HRESULT hr = S_OK;

	return hr;
}
